package net.qiqb.spring;

import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import net.qiqb.core.domain.annotation.AggregateRoot;
import net.qiqb.core.domain.annotation.AttachedAggregate;
import net.qiqb.core.executing.annotation.Command;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.annotation.ClassPathBeanDefinitionScanner;
import org.springframework.context.annotation.ScannedGenericBeanDefinition;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.core.type.filter.AnnotationTypeFilter;

import java.lang.annotation.Annotation;
import java.util.HashSet;
import java.util.Set;

@Slf4j
public class ClassPathComponentScanner extends ClassPathBeanDefinitionScanner {

    private final Set<Class<? extends Annotation>> annotationClass = new HashSet<>();
    /**
     * 命令注解的定义
     */
    @Getter
    private final Set<BeanDefinition> commandBeanDefinition = new HashSet<>();
    @Getter
    private final Set<BeanDefinition> aggregateRootBeanDefinition = new HashSet<>();
    @Getter
    private final Set<BeanDefinition> attachAggregateBeanDefinition = new HashSet<>();

    public ClassPathComponentScanner(BeanDefinitionRegistry registry) {
        super(registry, false);
        annotationClass.add(Command.class);
        annotationClass.add(AggregateRoot.class);
        annotationClass.add(AttachedAggregate.class);

    }

    @Override
    protected boolean checkCandidate(String beanName, BeanDefinition beanDefinition) throws IllegalStateException {
        if (super.checkCandidate(beanName, beanDefinition)) {
            // 自定义 annotationClass 的几个注解类不需要注册 spring 内
            if (beanDefinition instanceof ScannedGenericBeanDefinition scannedGenericBeanDefinition) {
                final AnnotationMetadata metadata = scannedGenericBeanDefinition.getMetadata();
                if (metadata.hasAnnotation(Command.class.getName())) {
                    commandBeanDefinition.add(beanDefinition);
                    return false;
                }
                if (metadata.hasAnnotation(AggregateRoot.class.getName())) {
                    aggregateRootBeanDefinition.add(beanDefinition);
                    return false;
                }

                if (metadata.hasAnnotation(AttachedAggregate.class.getName())) {
                    attachAggregateBeanDefinition.add(beanDefinition);
                    return false;
                }
                if (metadata.hasAnnotation(AttachedAggregate.class.getName())) {
                    attachAggregateBeanDefinition.add(beanDefinition);
                    return false;
                }
                // ModuleService 修饰的默认添加到 spring 容器中

            }
            return true;
        }

        return false;
    }

    public void registerFilters() {

        // if specified, use the given annotation and / or marker interface
        if (!this.annotationClass.isEmpty()) {
            this.annotationClass.forEach(a -> {
                addIncludeFilter(new AnnotationTypeFilter(a));
            });

        }

    }
}
